//常用宏的封装

#ifndef __macro_H__
#define __macro_H__

#include "util.h"
#include <string>
#include <assert.h>


/*
__builtin_expect 是 GCC 和 LLVM 编译器提供的内置函数，它告诉编译器条件的期望结果，第二个参数为期望值
1 表示期望条件为真。所以，FRAMEWORK_LIKELY(x) 实际上是告诉编译器条件 x 大概率为真。
0 表示期望条件为假。所以，FRAMEWORK_UNLIKELY(x) 实际上是告诉编译器条件 x 大概率为假。
!!的作用是将函数的返回值转换为bool值（0 或 1）
*/

#if defined __GNUC__ || defined __llvm__
#   define FRAMEWORK_LIKELY(x)       __builtin_expect(!!(x), 1)
#   define FRAMEWORK_UNLIKELY(x)     __builtin_expect(!!(x), 0)
#else  //如果不是 GCC 和 LLVM 则什么都不做
#   define FRAMEWORK_LIKELY(x)      (x)
#   define FRAMEWORK_UNLIKELY(x)    (x)
#endif


/* 
assert 断言
void assert(int expression);
如果expression的值为false，则assert()函数将会打印错误信息到标准错误输出，然后调用abort()函数终止程序运行。
如果expression的值为true，则assert()函数不做任何操作，程序继续正常运行。
assert()函数只在调试模式下起作用，在发布模式下会被编译器忽略
*/

//断言宏封装
#define FRAMEWORK_ASSERT(x) \
    if(FRAMEWORK_UNLIKELY(!(x))) {   \
        FRAMEWORK_LOG_ERROR(FRAMEWORK_LOG_ROOT()) << "ASSERTION: " #x \
            << "\nbacktrace:\n" /*回溯跟踪*/   \
            << framework::BacktraceToString(100, 2, "\t"); \
        assert(x); \
    }   

//断言宏封装
#define FRAMEWORK_ASSERT2(x, w)  \
    if(FRAMEWORK_UNLIKELY(!(x))) {  \
        FRAMEWORK_LOG_ERROR(FRAMEWORK_LOG_ROOT()) << "ASSERTION " #x \
            << "\n" << w  \
            << "\nbacktrace:\n" /*回溯跟踪*/   \
            << framework::BacktraceToString(100, 2, "\t"); \
        assert(x); \
    }


#endif
